# =============================================================================
# April 24 2025
# R code used to produce all results, tables, and figures in the SI Online Appendix G.4
# Rebecca Cordell
# Unpacking the Role of In-Group Bias in US Public Opinion on Human Rights Violations
# American Journal of Political Science
# https://doi.org/10.7910/DVN/TGAL7M
# =============================================================================

# Clear work environment
rm(list=ls())

# Install Packages
#install.packages("dplyr")
#install.packages("ggplot2")
#install.packages("forcats")
#install.packages("ggpubr")
#install.packages("ggeasy")
#install.packages("lemon")
#install.packages("sandwich")
#install.packages("survey")
#install.packages("lmtest")
#install.packages("remotes")
#remotes::install_version("cregg", version = "0.4.0")

# Required Packages
library("dplyr")
library("ggplot2")
library("forcats")
library("ggpubr")
library("sandwich")
library("survey")
library("lmtest")
library("cregg")
library("ggeasy")
library("lemon")

options(scipen = 999)
options(warn=-1)

# -----------------------------------------------------------------------------
# Read in data
# -----------------------------------------------------------------------------

hr_survey<-read.csv("cordell_ingroupbiashumanrights_data.csv", header=TRUE, stringsAsFactors = FALSE)

# =============================================================================
# Figure G.4: Effect of Group Identity Attributes, Attribute Order Effects Test
# =============================================================================

# -----------------------------------------------------------------------------
# Perpetrator Attribute
# -----------------------------------------------------------------------------

# First row

# Subset profiles assessed in first row of conjoint survey experiment
first_row_perp<-hr_survey[hr_survey$perp_order==1,]

# Convert regression variables into factors
factor_vars <- c("perp_match", "agent", "type", "scope", "targ_nonstate",
                 "targ_race_match", "targ_relig_match", "targ_citiz_match",
                 "frame", "elite_match")
first_row_perp[factor_vars] <- lapply(first_row_perp[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_perp_1_m1 <- cregg::cj(first_row_perp, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
group_vars <- c("perp_match")
fig_g4_perp_1_m1 <- fig_g4_perp_1_m1[fig_g4_perp_1_m1$feature %in% group_vars,]

# Model 2
fig_g4_perp_1_m2 <- cregg::cj(first_row_perp, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_perp_1_m2 <- fig_g4_perp_1_m2[fig_g4_perp_1_m2$feature %in% group_vars,]

# Second row

# Subset profiles assessed in second row of conjoint survey experiment
second_row_perp<-hr_survey[hr_survey$perp_order==2,]

# Convert regression variables into factors
second_row_perp[factor_vars] <- lapply(second_row_perp[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_perp_2_m1 <- cregg::cj(second_row_perp, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_perp_2_m1 <- fig_g4_perp_2_m1[fig_g4_perp_2_m1$feature %in% group_vars,]

# Model 2
fig_g4_perp_2_m2 <- cregg::cj(second_row_perp, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_perp_2_m2 <- fig_g4_perp_2_m2[fig_g4_perp_2_m2$feature %in% group_vars,]

# Third row

# Subset profiles assessed in thid row of conjoint survey experiment
third_row_perp<-hr_survey[hr_survey$perp_order==3,]

# Convert regression variables into factors
third_row_perp[factor_vars] <- lapply(third_row_perp[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_perp_3_m1 <- cregg::cj(third_row_perp, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_perp_3_m1 <- fig_g4_perp_3_m1[fig_g4_perp_3_m1$feature %in% group_vars,]

# Model 2
fig_g4_perp_3_m2 <- cregg::cj(third_row_perp, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_perp_3_m2 <- fig_g4_perp_3_m2[fig_g4_perp_3_m2$feature %in% group_vars,]

# Fourth row

# Subset profiles assessed in fourth row of conjoint survey experiment
fourth_row_perp<-hr_survey[hr_survey$perp_order==4,]

# Convert regression variables into factors
fourth_row_perp[factor_vars] <- lapply(fourth_row_perp[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_perp_4_m1 <- cregg::cj(fourth_row_perp, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_perp_4_m1 <- fig_g4_perp_4_m1[fig_g4_perp_4_m1$feature %in% group_vars,]

# Model 2
fig_g4_perp_4_m2 <- cregg::cj(fourth_row_perp, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_perp_4_m2 <- fig_g4_perp_4_m2[fig_g4_perp_4_m2$feature %in% group_vars,]

# Fifth row

# Subset profiles assessed in fifth row of conjoint survey experiment
fifth_row_perp<-hr_survey[hr_survey$perp_order==5,]

# Convert regression variables into factors
fifth_row_perp[factor_vars] <- lapply(fifth_row_perp[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_perp_5_m1 <- cregg::cj(fifth_row_perp, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_perp_5_m1 <- fig_g4_perp_5_m1[fig_g4_perp_5_m1$feature %in% group_vars,]

# Model 2
fig_g4_perp_5_m2 <- cregg::cj(fifth_row_perp, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_perp_5_m2 <- fig_g4_perp_5_m2[fig_g4_perp_5_m2$feature %in% group_vars,]

# -----------------------------------------------------------------------------
# Target Attributes
# -----------------------------------------------------------------------------

# First row

# Subset profiles assessed in first row of conjoint survey experiment
first_row_targ<-hr_survey[hr_survey$targ_order==1,]

# Convert regression variables into factors
factor_vars <- c("perp_match", "agent", "type", "scope", "targ_nonstate",
                 "targ_race_match", "targ_relig_match", "targ_citiz_match",
                 "frame", "elite_match")
first_row_targ[factor_vars] <- lapply(first_row_targ[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_targ_1_m1 <- cregg::cj(first_row_targ, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
group_vars <- c("targ_race_match", "targ_relig_match", "targ_citiz_match")
fig_g4_targ_1_m1 <- fig_g4_targ_1_m1[fig_g4_targ_1_m1$feature %in% group_vars,]

# Model 2
fig_g4_targ_1_m2 <- cregg::cj(first_row_targ, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_targ_1_m2 <- fig_g4_targ_1_m2[fig_g4_targ_1_m2$feature %in% group_vars,]

# Second row

# Subset profiles assessed in second row of conjoint survey experiment
second_row_targ<-hr_survey[hr_survey$targ_order==2,]

# Convert regression variables into factors
second_row_targ[factor_vars] <- lapply(second_row_targ[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_targ_2_m1 <- cregg::cj(second_row_targ, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_targ_2_m1 <- fig_g4_targ_2_m1[fig_g4_targ_2_m1$feature %in% group_vars,]

# Model 2
fig_g4_targ_2_m2 <- cregg::cj(second_row_targ, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_targ_2_m2 <- fig_g4_targ_2_m2[fig_g4_targ_2_m2$feature %in% group_vars,]

# Third row

# Subset profiles assessed in thid row of conjoint survey experiment
third_row_targ<-hr_survey[hr_survey$targ_order==3,]

# Convert regression variables into factors
third_row_targ[factor_vars] <- lapply(third_row_targ[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_targ_3_m1 <- cregg::cj(third_row_targ, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_targ_3_m1 <- fig_g4_targ_3_m1[fig_g4_targ_3_m1$feature %in% group_vars,]

# Model 2
fig_g4_targ_3_m2 <- cregg::cj(third_row_targ, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_targ_3_m2 <- fig_g4_targ_3_m2[fig_g4_targ_3_m2$feature %in% group_vars,]

# Fourth row

# Subset profiles assessed in fourth row of conjoint survey experiment
fourth_row_targ<-hr_survey[hr_survey$targ_order==4,]

# Convert regression variables into factors
fourth_row_targ[factor_vars] <- lapply(fourth_row_targ[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_targ_4_m1 <- cregg::cj(fourth_row_targ, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_targ_4_m1 <- fig_g4_targ_4_m1[fig_g4_targ_4_m1$feature %in% group_vars,]

# Model 2
fig_g4_targ_4_m2 <- cregg::cj(fourth_row_targ, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_targ_4_m2 <- fig_g4_targ_4_m2[fig_g4_targ_4_m2$feature %in% group_vars,]

# Fifth row

# Subset profiles assessed in fifth row of conjoint survey experiment
fifth_row_targ<-hr_survey[hr_survey$targ_order==5,]

# Convert regression variables into factors
fifth_row_targ[factor_vars] <- lapply(fifth_row_targ[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_targ_5_m1 <- cregg::cj(fifth_row_targ, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_targ_5_m1 <- fig_g4_targ_5_m1[fig_g4_targ_5_m1$feature %in% group_vars,]

# Model 2
fig_g4_targ_5_m2 <- cregg::cj(fifth_row_targ, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_targ_5_m2 <- fig_g4_targ_5_m2[fig_g4_targ_5_m2$feature %in% group_vars,]

# -----------------------------------------------------------------------------
# Elite Attribute
# -----------------------------------------------------------------------------

# First row

# Subset profiles assessed in first row of conjoint survey experiment
first_row_elite<-hr_survey[hr_survey$elite_order==1,]

# Convert regression variables into factors
factor_vars <- c("perp_match", "agent", "type", "scope", "targ_nonstate",
                 "targ_race_match", "targ_relig_match", "targ_citiz_match",
                 "frame", "elite_match")
first_row_elite[factor_vars] <- lapply(first_row_elite[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_elite_1_m1 <- cregg::cj(first_row_elite, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
group_vars <- c("elite_match")
fig_g4_elite_1_m1 <- fig_g4_elite_1_m1[fig_g4_elite_1_m1$feature %in% group_vars,]

# Model 2
fig_g4_elite_1_m2 <- cregg::cj(first_row_elite, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_elite_1_m2 <- fig_g4_elite_1_m2[fig_g4_elite_1_m2$feature %in% group_vars,]

# Second row

# Subset profiles assessed in second row of conjoint survey experiment
second_row_elite<-hr_survey[hr_survey$elite_order==2,]

# Convert regression variables into factors
second_row_elite[factor_vars] <- lapply(second_row_elite[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_elite_2_m1 <- cregg::cj(second_row_elite, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_elite_2_m1 <- fig_g4_elite_2_m1[fig_g4_elite_2_m1$feature %in% group_vars,]

# Model 2
fig_g4_elite_2_m2 <- cregg::cj(second_row_elite, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_elite_2_m2 <- fig_g4_elite_2_m2[fig_g4_elite_2_m2$feature %in% group_vars,]

# Third row

# Subset profiles assessed in thid row of conjoint survey experiment
third_row_elite<-hr_survey[hr_survey$elite_order==3,]

# Convert regression variables into factors
third_row_elite[factor_vars] <- lapply(third_row_elite[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_elite_3_m1 <- cregg::cj(third_row_elite, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_elite_3_m1 <- fig_g4_elite_3_m1[fig_g4_elite_3_m1$feature %in% group_vars,]

# Model 2
fig_g4_elite_3_m2 <- cregg::cj(third_row_elite, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_elite_3_m2 <- fig_g4_elite_3_m2[fig_g4_elite_3_m2$feature %in% group_vars,]

# Fourth row

# Subset profiles assessed in fourth row of conjoint survey experiment
fourth_row_elite<-hr_survey[hr_survey$elite_order==4,]

# Convert regression variables into factors
fourth_row_elite[factor_vars] <- lapply(fourth_row_elite[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_elite_4_m1 <- cregg::cj(fourth_row_elite, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_elite_4_m1 <- fig_g4_elite_4_m1[fig_g4_elite_4_m1$feature %in% group_vars,]

# Model 2
fig_g4_elite_4_m2 <- cregg::cj(fourth_row_elite, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_elite_4_m2 <- fig_g4_elite_4_m2[fig_g4_elite_4_m2$feature %in% group_vars,]

# Fifth row

# Subset profiles assessed in fifth row of conjoint survey experiment
fifth_row_elite<-hr_survey[hr_survey$elite_order==5,]

# Convert regression variables into factors
fifth_row_elite[factor_vars] <- lapply(fifth_row_elite[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_g4_elite_5_m1 <- cregg::cj(fifth_row_elite, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_elite_5_m1 <- fig_g4_elite_5_m1[fig_g4_elite_5_m1$feature %in% group_vars,]

# Model 2
fig_g4_elite_5_m2 <- cregg::cj(fifth_row_elite, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm")

# Subset group identity dummy variables
fig_g4_elite_5_m2 <- fig_g4_elite_5_m2[fig_g4_elite_5_m2$feature %in% group_vars,]

# -----------------------------------------------------------------------------
# Prepare first row figures
# -----------------------------------------------------------------------------

# Combine models
fig_g4_perp_1_all <- rbind(fig_g4_perp_1_m1, fig_g4_perp_1_m2)
fig_g4_targ_1_all <- rbind(fig_g4_targ_1_m1, fig_g4_targ_1_m2)
fig_g4_elite_1_all <- rbind(fig_g4_elite_1_m1, fig_g4_elite_1_m2)
fig_g4_1_all <-rbind(fig_g4_perp_1_all, fig_g4_targ_1_all, fig_g4_elite_1_all)

# Create group identity variable labels
variable_labels <- c(
  "perp_match" = "Perpetrator (partisanship)",
  "targ_race_match" = "Target (race)",
  "targ_relig_match" = "Target (religion)",
  "targ_citiz_match" = "Target (citizenship)",
  "elite_match" = "Elite cue (partisanship)"
)
fig_g4_1_all <- dplyr::bind_rows(
  fig_g4_1_all,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Create respondents variable (in-groups vs. out-groups)
fig_g4_1_all <- fig_g4_1_all %>%
  mutate(
    Respondents = case_when(
      grepl("_in", level) ~ "In-group",
      grepl("_out", level) ~ "Out-group",
      level %in% c("Perpetrator (partisanship)", "Target (race)", 
                   "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group",
      TRUE ~ level
    ),
    Respondents = factor(Respondents, levels = c("In-group", "Out-group"))
  )

# Set factor order
level_order <- c(
  "Perpetrator (partisanship)", "perp_in", "perp_out",
  "Target (race)", "race_in", "race_out",
  "Target (religion)", "relig_in", "relig_out",
  "Target (citizenship)", "citiz_in", "citiz_out",
  "Elite cue (partisanship)", "elite_in", "elite_out"
)
fig_g4_1_all <- fig_g4_1_all %>%
  mutate(level = factor(level, levels = level_order) %>% fct_rev())

# Separate models
fig_g4_1_m1 <- filter(fig_g4_1_all, outcome == "outcome1")
fig_g4_1_m2 <- filter(fig_g4_1_all, outcome == "outcome2")

# -----------------------------------------------------------------------------
# Create first row figures
# -----------------------------------------------------------------------------

# Create panel (a) Disapproval forced-choice
fig_g4_1_m1_plot <- ggplot(fig_g4_1_m1, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(a) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (b) Disapproval ratings-based
fig_g4_1_m2_plot <- ggplot(fig_g4_1_m2, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(b) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Combine figures
fig_g4_1_plot_all<-ggarrange(fig_g4_1_m1_plot, NULL, fig_g4_1_m2_plot,
                             nrow = 1, common.legend = T, legend = "bottom", ncol=3, widths = c(1, 0.09, 1))
fig_g4_1_plot_all<-annotate_figure(fig_g4_1_plot_all, top = text_grob("First row", size = 14))

# -----------------------------------------------------------------------------
# Prepare second row figures
# -----------------------------------------------------------------------------

# Combine models
fig_g4_perp_2_all <- rbind(fig_g4_perp_2_m1, fig_g4_perp_2_m2)
fig_g4_targ_2_all <- rbind(fig_g4_targ_2_m1, fig_g4_targ_2_m2)
fig_g4_elite_2_all <- rbind(fig_g4_elite_2_m1, fig_g4_elite_2_m2)
fig_g4_2_all <-rbind(fig_g4_perp_2_all, fig_g4_targ_2_all, fig_g4_elite_2_all)

# Create group identity variable labels
fig_g4_2_all <- dplyr::bind_rows(
  fig_g4_2_all,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Create respondents variable (in-groups vs. out-groups)
fig_g4_2_all <- fig_g4_2_all %>%
  mutate(
    Respondents = case_when(
      grepl("_in", level) ~ "In-group",
      grepl("_out", level) ~ "Out-group",
      level %in% c("Perpetrator (partisanship)", "Target (race)", 
                   "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group",
      TRUE ~ level
    ),
    Respondents = factor(Respondents, levels = c("In-group", "Out-group"))
  )

# Set factor order
fig_g4_2_all <- fig_g4_2_all %>%
  mutate(level = factor(level, levels = level_order) %>% fct_rev())

# Separate models
fig_g4_2_m1 <- filter(fig_g4_2_all, outcome == "outcome1")
fig_g4_2_m2 <- filter(fig_g4_2_all, outcome == "outcome2")

# -----------------------------------------------------------------------------
# Create second row figures
# -----------------------------------------------------------------------------

# Create panel (c) Disapproval forced-choice
fig_g4_2_m1_plot <- ggplot(fig_g4_2_m1, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(c) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (d) Disapproval ratings-based
fig_g4_2_m2_plot <- ggplot(fig_g4_2_m2, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(d) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Combine figures
fig_g4_2_plot_all<-ggarrange(fig_g4_2_m1_plot, NULL, fig_g4_2_m2_plot,
                             nrow = 1, common.legend = T, legend = "bottom", ncol=3, widths = c(1, 0.09, 1))
fig_g4_2_plot_all<-annotate_figure(fig_g4_2_plot_all, top = text_grob("Second row", size = 14))

# -----------------------------------------------------------------------------
# Prepare third row figures
# -----------------------------------------------------------------------------

# Combine models
fig_g4_perp_3_all <- rbind(fig_g4_perp_3_m1, fig_g4_perp_3_m2)
fig_g4_targ_3_all <- rbind(fig_g4_targ_3_m1, fig_g4_targ_3_m2)
fig_g4_elite_3_all <- rbind(fig_g4_elite_3_m1, fig_g4_elite_3_m2)
fig_g4_3_all <-rbind(fig_g4_perp_3_all, fig_g4_targ_3_all, fig_g4_elite_3_all)

# Create group identity variable labels
fig_g4_3_all <- dplyr::bind_rows(
  fig_g4_3_all,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Create respondents variable (in-groups vs. out-groups)
fig_g4_3_all <- fig_g4_3_all %>%
  mutate(
    Respondents = case_when(
      grepl("_in", level) ~ "In-group",
      grepl("_out", level) ~ "Out-group",
      level %in% c("Perpetrator (partisanship)", "Target (race)", 
                   "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group",
      TRUE ~ level
    ),
    Respondents = factor(Respondents, levels = c("In-group", "Out-group"))
  )

# Set factor order
fig_g4_3_all <- fig_g4_3_all %>%
  mutate(level = factor(level, levels = level_order) %>% fct_rev())

# Separate models
fig_g4_3_m1 <- filter(fig_g4_3_all, outcome == "outcome1")
fig_g4_3_m2 <- filter(fig_g4_3_all, outcome == "outcome2")

# -----------------------------------------------------------------------------
# Create third row figures
# -----------------------------------------------------------------------------

# Create panel (e) Disapproval forced-choice
fig_g4_3_m1_plot <- ggplot(fig_g4_3_m1, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(e) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (f) Disapproval ratings-based
fig_g4_3_m2_plot <- ggplot(fig_g4_3_m2, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(f) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Combine figures
fig_g4_3_plot_all<-ggarrange(fig_g4_3_m1_plot, NULL, fig_g4_3_m2_plot,
                             nrow = 1, common.legend = T, legend = "bottom", ncol=3, widths = c(1, 0.09, 1))
fig_g4_3_plot_all<-annotate_figure(fig_g4_3_plot_all, top = text_grob("Third row", size = 14))

# -----------------------------------------------------------------------------
# Prepare fourth row figures
# -----------------------------------------------------------------------------

# Combine models
fig_g4_perp_4_all <- rbind(fig_g4_perp_4_m1, fig_g4_perp_4_m2)
fig_g4_targ_4_all <- rbind(fig_g4_targ_4_m1, fig_g4_targ_4_m2)
fig_g4_elite_4_all <- rbind(fig_g4_elite_4_m1, fig_g4_elite_4_m2)
fig_g4_4_all <-rbind(fig_g4_perp_4_all, fig_g4_targ_4_all, fig_g4_elite_4_all)

# Create group identity variable labels
fig_g4_4_all <- dplyr::bind_rows(
  fig_g4_4_all,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Create respondents variable (in-groups vs. out-groups)
fig_g4_4_all <- fig_g4_4_all %>%
  mutate(
    Respondents = case_when(
      grepl("_in", level) ~ "In-group",
      grepl("_out", level) ~ "Out-group",
      level %in% c("Perpetrator (partisanship)", "Target (race)", 
                   "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group",
      TRUE ~ level
    ),
    Respondents = factor(Respondents, levels = c("In-group", "Out-group"))
  )

# Set factor order
fig_g4_4_all <- fig_g4_4_all %>%
  mutate(level = factor(level, levels = level_order) %>% fct_rev())

# Separate models
fig_g4_4_m1 <- filter(fig_g4_4_all, outcome == "outcome1")
fig_g4_4_m2 <- filter(fig_g4_4_all, outcome == "outcome2")

# -----------------------------------------------------------------------------
# Create fourth row figures
# -----------------------------------------------------------------------------

# Create panel (g) Disapproval forced-choice
fig_g4_4_m1_plot <- ggplot(fig_g4_4_m1, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(g) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (h) Disapproval ratings-based
fig_g4_4_m2_plot <- ggplot(fig_g4_4_m2, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(h) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Combine figures
fig_g4_4_plot_all<-ggarrange(fig_g4_4_m1_plot, NULL, fig_g4_4_m2_plot,
                             nrow = 1, common.legend = T, legend = "bottom", ncol=3, widths = c(1, 0.09, 1))
fig_g4_4_plot_all<-annotate_figure(fig_g4_4_plot_all, top = text_grob("Fourth row", size = 14))

# -----------------------------------------------------------------------------
# Prepare fifth row figures
# -----------------------------------------------------------------------------

# Combine models
fig_g4_perp_5_all <- rbind(fig_g4_perp_5_m1, fig_g4_perp_5_m2)
fig_g4_targ_5_all <- rbind(fig_g4_targ_5_m1, fig_g4_targ_5_m2)
fig_g4_elite_5_all <- rbind(fig_g4_elite_5_m1, fig_g4_elite_5_m2)
fig_g4_5_all <-rbind(fig_g4_perp_5_all, fig_g4_targ_5_all, fig_g4_elite_5_all)

# Create group identity variable labels
fig_g4_5_all <- dplyr::bind_rows(
  fig_g4_5_all,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Create respondents variable (in-groups vs. out-groups)
fig_g4_5_all <- fig_g4_5_all %>%
  mutate(
    Respondents = case_when(
      grepl("_in", level) ~ "In-group",
      grepl("_out", level) ~ "Out-group",
      level %in% c("Perpetrator (partisanship)", "Target (race)", 
                   "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group",
      TRUE ~ level
    ),
    Respondents = factor(Respondents, levels = c("In-group", "Out-group"))
  )

# Set factor order
fig_g4_5_all <- fig_g4_5_all %>%
  mutate(level = factor(level, levels = level_order) %>% fct_rev())

# Separate models
fig_g4_5_m1 <- filter(fig_g4_5_all, outcome == "outcome1")
fig_g4_5_m2 <- filter(fig_g4_5_all, outcome == "outcome2")

# -----------------------------------------------------------------------------
# Create fifth row figures
# -----------------------------------------------------------------------------

# Create panel (i) Disapproval forced-choice
fig_g4_5_m1_plot <- ggplot(fig_g4_5_m1, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(i) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (j) Disapproval ratings-based
fig_g4_5_m2_plot <- ggplot(fig_g4_5_m2, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(j) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Combine figures
fig_g4_5_plot_all<-ggarrange(fig_g4_5_m1_plot, NULL, fig_g4_5_m2_plot,
                             nrow = 1, common.legend = T, legend = "bottom", ncol=3, widths = c(1, 0.09, 1))
fig_g4_5_plot_all<-annotate_figure(fig_g4_5_plot_all, top = text_grob("Fifth row", size = 14))

# Print Figure G.4
pdf('figure_g4.pdf', width = 8, height = 15)
ggarrange(fig_g4_1_plot_all, fig_g4_2_plot_all, fig_g4_3_plot_all, fig_g4_4_plot_all, fig_g4_5_plot_all,
          nrow = 5, common.legend = T, legend = "bottom", ncol=1)
dev.off()